/**
 * 
 */
package optimization.naturalOptimization.searchSpace;

import optimization.IdentificationI;
import optimization.naturalOptimization.NaturalOptimization;

/**
 * Abstract class to implement a search space.
 * 
 * @author Kevin Wagner
 * @version 1.0
 * @param <T>
 *            Type of Search Space
 * 
 */
public abstract class SearchSpace<T> implements IdentificationI {

	private int dimensionality = 10;
	private T[] boundaries = null;
	private NaturalOptimization parentOptimization;


	/**
	 * Creates a new search space with a given Optimization algorithm.
	 * 
	 * @param no
	 *            Natural Optimization
	 */
	public SearchSpace(NaturalOptimization no) {
		this.parentOptimization = no;
	}

	/**
	 * Returns the dimensionality of the search space.
	 * 
	 * @return the dimensionality
	 */
	public int getDimensionality() {
		return dimensionality;
	}

	/**
	 * Sets the dimensionality of the search space.
	 * 
	 * @param dimensionality
	 *            new dimensionality
	 */
	public void setDimensionality(int dimensionality) {
		this.dimensionality = dimensionality;
	}

	/**
	 * Returns the boundaries of the search space.
	 * 
	 * @return the boundaries
	 */
	public T[] getBoundaries() {
		return boundaries;
	}

	/**
	 * Sets the boundaries of the search space.
	 * 
	 * @param boundaries
	 *            new boundaries
	 */
	public void setBoundaries(T[] boundaries) {
		this.boundaries = boundaries;
	}

	/**
	 * Checks the position or feasibility.
	 * 
	 * @param position
	 *            position to check
	 * @return {@code TRUE} if position is feasible, {@code FALSE} if not.
	 */
	public abstract boolean isFeasible(T position);

	/**
	 * Creates a new random position by using the boundaries. If no boundaries
	 * are available every dimension gets a standard range.
	 * 
	 * @return random position
	 */
	public abstract T createRandomPosition();

	/**
	 * Creates a new positive random vector by using the boundaries. If no
	 * boundaries are available every dimension gets a standard range.
	 * 
	 * @return positive random vector
	 */
	public abstract T createPositiveRandomVector();

	/**
	 * Creates a new positive vector by using the boundaries and the given
	 * percentage. If no boundaries are available every dimension gets a
	 * standard range.
	 * 
	 * @param percent
	 *            percent of dimension size
	 * 
	 * @return positive vector (upperBound-lowerBound)*percent
	 */
	public abstract T createPositiveVector(double percent);

	/**
	 * Gives the string representation of a position in this search space
	 * 
	 * @param position
	 * @return the representation of the position as a string
	 */
	public abstract String toString(T position);

	/**
	 * Returns the parent optimization algorithm.
	 * 
	 * @return parent optimization algorithm
	 */
	public NaturalOptimization getParentOptimization() {
		return parentOptimization;
	}

	/**
	 * Returns the lower bounds of the search space.
	 * 
	 * @return lower bounds
	 */
	public abstract T getLowerBounds();

	/**
	 * Returns the upper bounds of the search space.
	 * 
	 * @return upper bounds
	 */
	public abstract T getUpperBounds();

	/**
	 * Checks the compatibility of the new boundaries.
	 * 
	 * @return status of compatibility
	 */
	public abstract boolean checkBoundariesCompatibility();

	/**
	 * Creates a position in the middle of the search space. If the there are no
	 * boundaries the method creates a null vector.
	 * 
	 * @return middle position
	 */
	public abstract T createMiddlePosition();

	/**
	 * Creates a velocity in search space with a given maximum value
	 * @param vmax maximum velocity
	 * @return U(-vmax,vmax)
	 */
	public abstract T createVelocity(double vmax);
	

}
